#include "FaceDetector.h"

#include "ObjectDetector.h"
#include "ImageUtility.h"

#include <QDebug>

Q_DECLARE_METATYPE(QVector<Face>)

FaceDetector::FaceDetector(float faceScale, QObject *parent) :
    QObject(parent),
    faceDetector(new ObjectDetector(ObjectDetector::FACE_FRONTAL, true, faceScale)),
    leftEyeDetector(new ObjectDetector(ObjectDetector::EYE_LEFT, true, 1.0f)),
    rightEyeDetector(new ObjectDetector(ObjectDetector::EYE_RIGHT, true, 1.0f)),
    eyeGlassesDetector(new ObjectDetector(ObjectDetector::EYE_WITH_GLASSES, true, 1.0f)),
    eyePairBigDetector(new ObjectDetector(ObjectDetector::EYE_PAIR_BIG, true, 1.0f)),
    eyeDetector(new ObjectDetector(ObjectDetector::EYE, true, 0.5f)),
    noseDetector(new ObjectDetector(ObjectDetector::NOSE, true, 0.5f)),
    mouthDetector(new ObjectDetector(ObjectDetector::MOUTH, true, 0.75f))
{
    qRegisterMetaType<QVector<Face> >();
}

QVector<Face> FaceDetector::detectFaces(QImage image)
{
    IplImage* ipl = ImageUtility::QImageToIplImage(image);

    QVector<Face> fullFaces;

    QVector<QRect> faces = faceDetector->detectObjects(ipl);

    foreach (QRect face, faces) {

//        noseDetector->setRegionOfInterest(QRect(face.x(), face.y() + face.height() * 0.25f,
//                                                face.width(), face.height() * 0.75f));
//        mouthDetector->setRegionOfInterest(QRect(face.x(), face.y() + face.height() * 0.65f,
//                                                 face.width(), face.height() * 0.35f));

//        QVector<QRect> eyes = this->findEyes(face, ipl);


//        QVector<QRect> noses = noseDetector->detectObjects(ipl);
//        QVector<QRect> mouths = mouthDetector->detectObjects(ipl);

        QRect eye1;// = eyes.count() > 0 ? eyes.first() : QRect();
        QRect eye2;// = eyes.count() > 1 ? eyes.last() : QRect();
        QRect nose;// = noses.count() > 0 ? noses.last() : QRect();
        QRect mouth;// = mouths.count() > 0 ? mouths.last() : QRect();
        fullFaces.append(Face(face, eye1, eye2, nose, mouth, image.copy(face)));
    }

    emit detectedFaces(fullFaces);

    cvReleaseImage(&ipl);

    return fullFaces;
}

QVector<QRect> FaceDetector::findEyes(QRect face, IplImage* image)
{
    QRect eyeRegion(face.x(), face.y(), face.width(), face.height() * 0.5f);
//    leftEyeDetector->setRegionOfInterest(eyeRegion);
//    rightEyeDetector->setRegionOfInterest(eyeRegion);
//    eyeGlassesDetector->setRegionOfInterest(eyeRegion);
    eyePairBigDetector->setRegionOfInterest(eyeRegion);
//    eyeDetector->setRegionOfInterest(eyeRegion);

//    QVector<QRect> leftEyes = leftEyeDetector->detectObjects(image);
//    QVector<QRect> rightEyes = rightEyeDetector->detectObjects(image);
//    QVector<QRect> eyeGlasses = eyeGlassesDetector->detectObjects(image);
    QVector<QRect> eyePairs = eyePairBigDetector->detectObjects(image);
//    QVector<QRect> eyes = eyeDetector->detectObjects(image);

    QVector<QRect> newEyes;
    foreach (QRect rect, eyePairs) {
        QRect first(rect.topLeft(), QSize(rect.width()/2, rect.height()));
        QRect second(rect.left() + rect.width()/2, rect.top(), rect.width()/2, rect.height());

        newEyes.append(first);
        newEyes.append(second);
    }

    return newEyes;
}
